home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / 68hc11 / fuzzy11a.arc / FUZZY11A.ASM next >
Assembly Source File  |  1991-12-04  |  9KB  |  241 lines

  1. *    Fuzzy Logic Inferrence Engine
  2. *
  3. *** Data structures and variables
  4. *
  5.     ORG    $0000        ;Beginning of HC11 RAM
  6. CURRENT_INS RMB    8        ;Storage for 8 8-bit inputs
  7. FUZ_OUTS    RMB    32        ;Storage for fuzzy outputs
  8. COG_OUTS    RMB    4        ;Defuzzified outputs
  9. LOWEST_IF RMB    1        ;Holds min grade of IF parts
  10. SUM_OF_FUZ RMB    2        ;11-bit sum of fuzzy outs
  11. SUM_OF_PROD RMB    3        ;19-bit sum of products
  12. COGDEX    RMB    1        ;Current out # for COG loop 0->4
  13. SUMDEX    RMB    1        ;Index for sum loop 8->0
  14.  
  15.     ORG    $B600        Beginning of HC11 EEPROM
  16. IN_MF_PTRS FDB    IN0MF        ;Addr of MF data for input 0
  17.     FDB    IN1MF        ;Addr of MF data for input 1
  18.     FDB    IN2MF        ;Addr of MF data for input 2
  19.     FDB    IN3MF        ;Addr of MF data for input 3
  20.     FDB    IN4MF        ;Addr of MF data for input 4
  21.     FDB    IN5MF        ;Addr of MF data for input 5
  22.     FDB    IN6MF        ;Addr of MF data for input 6
  23.     FDB    IN7MF        ;Addr of MF data for input 7
  24. *
  25. * Input membership functions are defined by four 8-bit values per
  26. * input label. Up to 8 labels per input so max size of MF data
  27. * structure is 8*8*4=256 bytes. Unused labels take no space.
  28. * Membership functions are trapezoids with the base greater than or
  29. * equal to the top. Values are entered into this program as the
  30. * X coordinates of 4 points but are stored as 2 points and 2 slopes.
  31. ***** MACRO Definition for input membership functions
  32. *
  33. INMF    MACR    ;For input membership functions
  34.     FCB    \0                        ;First inflection point
  35.     IFNE \1-\0                      ;Check for divide by zero
  36.      FCB    ($FF+((\1-\0)/3))/(\1-\0) ;If not, calc slope
  37.     ENDC
  38.     IFEQ \1-\0                      ;Check for divide by zero
  39.      FCB    $00                        ;Indicates vertical slope
  40.     ENDC
  41.     FCB    \2                        ;Third inflection point
  42.     IFNE \3-\2                      ;Check for divide by zero
  43.      FCB    ($FF+((\3-\2)/3))/(\3-\2) ;If not, calc slope
  44.     ENDC
  45.     IFEQ \3-\2                      ;Check for divide by zero
  46.      FCB    $00                        ;Indicates vertical slope
  47.     ENDC
  48.     ENDM
  49. *    
  50. *****
  51. INPUT_MFS EQU    *           ;Input membership functions
  52.  
  53. IN0MF    EQU    *                 ;(0) ROTATION
  54.     INMF    0,0,0,8*4             ;    (0) STOPPED
  55.     INMF    0,8*4,$FF,$FF        ;    (1) NOT_STOPPED
  56.  
  57. IN1MF    EQU    *                 ;(1) EXAMPLE1
  58.     INMF    $20,$40,$60,$A0      ;    (0) TEST1
  59.  
  60. IN2MF    EQU    *                 ;(2) TEMPERATURE
  61.     INMF    2*0,2*0,2*40,2*50       ;    (0) COLD
  62.     INMF    2*40,2*50,2*60,2*70  ;    (1) COOL
  63.     INMF    2*60,2*70,2*80,2*90  ;    (2) WARM
  64.     INMF    2*80,2*90,2*95,2*110 ;    (3) HOT
  65.     INMF    2*90,2*110,$FF,$FF   ;    (4) VERY_HOT
  66.  
  67. IN3MF    EQU    *                 ;(3) DAYS_SINCE_RAIN
  68.     INMF    $00,$00,$00,$08       ;    (0) NONE
  69.     INMF    $00,$10,$10,$18       ;    (1) SHORT
  70.     INMF    $10,$20,$28,$40       ;    (2) MEDIUM
  71.     INMF    $30,$40,$50,$60       ;    (3) LONG
  72.     INMF    $50,$70,$FF,$FF       ;    (4) VERY_LONG
  73.  
  74. IN4MF    EQU    *        ;Not used
  75. IN5MF    EQU    *        ;Not used
  76. IN6MF    EQU    *        ;Not used
  77. IN7MF    EQU    *        ;Not used
  78.  
  79. SGLTN_POS EQU    *        ;Output singleton positions
  80. OUT0MF    EQU    *        ;(0) WATERING_TIME
  81.     FCB    $00            ;(0) CUT_OFF
  82.     FCB    $10            ;(1) DECREASE_GREATLY
  83.     FCB    $40            ;(2) DECREASE
  84.     FCB    $80            ;(3) NORMAL
  85.     FCB    $B0            ;(4) INCREASE
  86.     FCB    $F0            ;(5) INCREASE_GREATLY
  87.     FCB    0,0        ;Unused; Must fill 8 per output
  88. OUT1MF    FCB    0,0,0,0,0,0,0,0    ;Not used
  89. OUT2MF    FCB    0,0,0,0,0,0,0,0    ;Not used
  90. OUT3MF    FCB    0,0,0,0,0,0,0,0    ;Not used
  91. *
  92. * Each If part is of the form 00AA AXXX where AAA is a label (0-7)
  93. * and XXX is an input (0-7). If parts are connected by ANDs. A rule
  94. * may have any number of if parts (usually 2-8). Then parts are of
  95. * the form 100Y YCCC where the MSB set indicates a then part, YY is
  96. * the output number (0-3), and CCC is the output label (singleton
  97. * 0-7). A rule may have any number of then parts (usually 1 or 2).
  98. * A $FF indicates the end of a series of rules (number not limited).
  99. *  
  100. *    FCB    INx + 8*LABa    ;If input XXX is label AAA
  101. *    FCB    $80+8*OUTy+LABc    ;Then output YY is label CCC
  102.  
  103. RULE_START EQU    *        ;Start of first rule
  104. * Example rule: If TEMPERATURE is VERY_HOT and DAYS_SINCE_RAIN is LONG
  105. * Then WATERING_TIME is INCREASE_GREATLY
  106. RULE_1    FCB    2+(8*4),3+(8*3),$80+(8*0)+5
  107. END_OF_RULE FCB    $FF
  108.  
  109. ***** Fuzzy Inferrence Engine Starts Here
  110. *
  111.     ORG    $B66B
  112. INFER_TOP LDX    #FUZ_OUTS    ;Point at first fuzzy output
  113.     LDAA    #32        ;32 fuzzy outputs
  114. CLR_OUTS    CLR    0,X        ;Clear a fuzzy output
  115.     INX            ;Point at next
  116.     DECA            ;Loop index
  117.     BNE    CLR_OUTS        ;Continue till all fuzzy outs 0
  118.     LDY    #RULE_START    ;Point to start of 1st rule
  119. RULE_TOP    LDAA    #$FF        ;Begin processing rule string
  120.     STAA    LOWEST_IF    ;Will hold grade of min if part
  121. IF_LOOP    LDAB    0,Y        ;Get rule byte 00AA AXXX; If X is A
  122.     BMI    THEN_LOOP    ;If MSB=1, exit to then loop
  123.     LDX    #CURRENT_INS    ;Point at current input data area
  124.     ANDB    #$07        ;Save only input number
  125.     PSHB            ;Will need input # again
  126.     ABX            ;Point to specific input data
  127.     LDAA    0,X        ;Get current input data
  128.     LDX    #IN_MF_PTRS    ;Point at offsets for input MFs
  129.     PULB            ;Recover input number 0000 0XXX
  130.     ABX            ;Point at pointer for this input #
  131.     LDX    0,X        ;Get pointer into MF data area
  132.     LDAB    0,Y        ;Get rule if part 00AA AXXX
  133.     ANDB    #$38        ;00AA A000 is 8 times AAA
  134.     LSRB            ;000A AA00 4 times AAA
  135.     ABX            ;X points at MF points & slopes
  136.     CMPA    0,X        ;Compare input data to MF pt1
  137.     BHS    NOT_SEG0        ;Branch if not segment zero
  138.     CLRB            ;In seg 0 grade is zero
  139.     BRA    HAVE_GRADE    ;Have grade of membership
  140. NOT_SEG0    CMPA    2,X        ;Compare input data to MF pt2
  141.     BHI    IS_SEG2        ;Branch if segment two
  142.     LDAB    1,X        ;Slope1 -> B
  143.     BEQ    JAM_FF        ;If vert slope, jam $FF
  144.     SUBA    0,X        ;Input value - pt1 -> A
  145.     MUL            ;Grade in B if D < $100
  146.     CPD    #$100        ;Check for overflow
  147.     BLO    HAVE_GRADE    ;If < $100 grade OK in B
  148. JAM_FF    LDAB    #$FF        ;Else limit B to $FF
  149.     BRA    HAVE_GRADE    ;Have grade of membership
  150. IS_SEG2    LDAB    3,X        ;Slope2 -> B
  151.     SUBA    2,X        ;Input value - pt2 -> A
  152.     MUL            ;Grade in B if D < $100
  153.     CPD    #$100        ;Check for overflow
  154.     BLO    B_OK        ;If < $100 value in B OK
  155.     LDAB    #$FF        ;Else limit B to $FF
  156. B_OK    LDAA    #$FF        ;Grade should be $FF - (B)
  157.     SBA            ;Grade of membership in B
  158. HAVE_GRADE CMPB    LOWEST_IF    ;Is grade lowest so far ?
  159.     BHS    NOT_LOWR        ;Branch if not lower
  160.     STAB    LOWEST_IF    ;If lower, replace lowest if
  161.     BNE    NOT_LOWR        ;Skip ahead if not zero
  162. FIND_THEN INY            ;Adv rule pointer to then part
  163.     LDAB    0,Y        ;Get next rule byte
  164.     BPL    FIND_THEN    ;MSB set means its a then part
  165. FIND_IF    INY            ;Adv rule pointer to if part
  166.     LDAB    0,Y        ;Get next rule byte
  167.     BPL    RULE_TOP        ;MSB clear means its an if part
  168.     CMPB    #$FF        ;$FF is no more rules marker
  169.     BNE    FIND_IF        ;Continue looking for if or $FF
  170.     BRA    DEFUZ        ;When all rules done, go defuzzify
  171. NOT_LOWR    INY            ;Point to next rule byte
  172.     BRA    IF_LOOP        ;Continue for all if parts
  173. THEN_LOOP LDX    #FUZ_OUTS    ;Point at fuzzy outputs
  174.     ANDB    #$1F        ;Save 8 times out # + label #
  175.     ABX            ;X points at fuzzy output
  176.     LDAA    LOWEST_IF    ;Grade of membership for rule
  177.     CMPA    0,X        ;Compare to fuzzy output
  178.     BLO    NOT_HIER        ;Branch if not higher
  179.     STAA    0,X        ;Grade is higher so update
  180. NOT_HIER    INY            ;Point to next rule byte
  181.     LDAB    0,Y        ;Get rule byte
  182.     BMI    CHK_END        ;If MSB=0 its a new rule
  183.     JMP    RULE_TOP        ;Else process next rule byte
  184. CHK_END    CMPB    #$FF        ;Check for end of rules flag
  185.     BNE    THEN_LOOP    ;If not $FF, must be a then part
  186. DEFUZ    LDY    #SGLTN_POS    ;Point at 1st output singleton
  187.     LDX    #FUZ_OUTS    ;Point at 1st fuzzy output
  188.     CLR    COGDEX        ;Loop index will run from 0->4
  189. COG_LOOP    LDAB    #8        ;8 fuzzy outs per COG output
  190.     STAB    SUMDEX        ;Inner loop runs 8->0
  191.     LDD    #$0000        ;Used for quicker clears
  192.     STD    SUM_OF_FUZ    ;Sum of fuzzy outputs
  193.     STD    SUM_OF_PROD+1    ;Low 16-bits of sum of products
  194.     STAA    SUM_OF_PROD    ;Upper 8-bits
  195. SUM_LOOP    LDAB    0,X        ;Get a fuzzy output
  196.     CLRA            ;Clear upper 8-bits
  197.     ADDD    SUM_OF_FUZ    ;Add to sum of fuzzy outputs
  198.     STD    SUM_OF_FUZ    ;Update RAM variable
  199.     LDAA    0,X        ;Get fuzzy output again
  200.     LDAB    0,Y        ;Get Output singleton position
  201.     MUL            ;Position times weight
  202.     ADDD    SUM_OF_PROD+1    ;Low 16-bits of sum of products
  203.     STD    SUM_OF_PROD+1    ;Update low 16-bits
  204.     LDAA    SUM_OF_PROD    ;Upper 8-bits
  205.     ADCA    #0        ;Add carry from 16-bit add
  206.     STAA    SUM_OF_PROD    ;Upper 8-bits of 24-bit sum
  207.     INY            ;Point at next singleton pos.
  208.     INX            ;Point at next fuzzy output
  209.     DEC    SUMDEX        ;Inner loop index
  210.     BNE    SUM_LOOP        ;For all labels this output
  211.     PSHX            ;Save index for now
  212.     CLRA            ;In case divide by zero
  213.     LDX    SUM_OF_FUZ    ;Demominator for divide
  214.     BEQ    SAV_OUT        ;Branch if denominator is 0
  215.     TST    SUM_OF_PROD    ;See if more than 16-bit
  216.     BNE    NUM_BIG        ;If not zero, # is > 16-bits
  217.     LDD    SUM_OF_PROD+1    ;Numerator for divide
  218.     IDIV            ;Result in low 8-bits of X
  219.     XGDX            ;Result now in B
  220.     TBA            ;Move result to A
  221.     BRA    SAV_OUT        ;Go save output
  222. NUM_BIG    LDD    SUM_OF_PROD    ;Numerator upper 16 of 24-bit
  223.     TST    SUM_OF_PROD+2    ;Check for rounding error
  224.     BPL    NO_ROUND        ;If MSB clear, don't round
  225.     ADDD    #1        ;Round numerator up 1
  226. NO_ROUND    FDIV            ;D/X -> X, use upper 8 of 16
  227.     XGDX            ;Result now in A
  228. SAV_OUT    LDX    #COG_OUTS    ;Point to 1st defuz output
  229.     LDAB    COGDEX        ;Curent output number
  230.     ABX            ;Point to correct output
  231.     STAA    0,X        ;Update defuzzified output
  232.     PULX            ;Recover index
  233.     INCB            ;Increment loop index
  234.     STAB    COGDEX        ;Update
  235.     CMPB    #4        ;Done with all four outs?
  236.     BNE    COG_LOOP        ;If not, continue loop
  237.  
  238. * Inference engine has completed one pass of all rules.
  239.  
  240.